#!/bin/bash

# 数据网关打包脚本
# 作者: Data Gateway Team
# 版本: 1.0.0

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

log_debug() {
    echo -e "${BLUE}[DEBUG]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

# 显示帮助信息
show_help() {
    echo "数据网关打包脚本"
    echo ""
    echo "用法: $0 [选项]"
    echo ""
    echo "选项:"
    echo "  -h, --help              显示帮助信息"
    echo "  -v, --version VERSION   指定版本号"
    echo "  -t, --type TYPE         打包类型 (jar/docker/all)"
    echo "  -o, --output DIR        输出目录"
    echo "  --skip-tests            跳过测试"
    echo "  --skip-docker           跳过Docker构建"
    echo "  --clean                 清理构建目录"
    echo ""
    echo "示例:"
    echo "  $0 --version 1.0.1 --type all    # 打包所有类型"
    echo "  $0 --type jar --skip-tests        # 仅打包JAR"
    echo "  $0 --type docker --version 1.0.1  # 仅构建Docker镜像"
}

# 检查依赖
check_dependencies() {
    log_info "检查打包依赖..."
    
    # 检查Java
    if ! command -v java &> /dev/null; then
        log_error "Java未安装或不在PATH中"
        exit 1
    fi
    
    # 检查Maven
    if ! command -v mvn &> /dev/null; then
        log_error "Maven未安装或不在PATH中"
        exit 1
    fi
    
    # 检查Docker（如果需要）
    if [ "$PACKAGE_TYPE" = "docker" ] || [ "$PACKAGE_TYPE" = "all" ]; then
        if ! command -v docker &> /dev/null; then
            log_error "Docker未安装或不在PATH中"
            exit 1
        fi
    fi
    
    log_info "依赖检查完成"
}

# 清理构建目录
clean_build() {
    log_info "清理构建目录..."
    
    if [ -d "target" ]; then
        rm -rf target
        log_info "已清理target目录"
    fi
    
    if [ -d "$OUTPUT_DIR" ]; then
        rm -rf "$OUTPUT_DIR"
        log_info "已清理输出目录: $OUTPUT_DIR"
    fi
    
    log_info "清理完成"
}

# 创建输出目录
create_output_dir() {
    log_info "创建输出目录: $OUTPUT_DIR"
    mkdir -p "$OUTPUT_DIR"
    mkdir -p "$OUTPUT_DIR/jar"
    mkdir -p "$OUTPUT_DIR/docker"
    mkdir -p "$OUTPUT_DIR/config"
    mkdir -p "$OUTPUT_DIR/scripts"
    mkdir -p "$OUTPUT_DIR/docs"
}

# 打包JAR文件
package_jar() {
    log_info "打包JAR文件..."
    
    # 设置Maven参数
    mvn_args="package"
    
    if [ "$SKIP_TESTS" = true ]; then
        mvn_args="$mvn_args -DskipTests"
    fi
    
    # 执行打包
    log_info "执行Maven打包: $mvn_args"
    mvn $mvn_args
    
    # 复制JAR文件
    jar_file="target/data-gateway-${VERSION}.jar"
    if [ -f "$jar_file" ]; then
        cp "$jar_file" "$OUTPUT_DIR/jar/"
        log_info "JAR文件已复制: $jar_file"
    else
        log_error "JAR文件不存在: $jar_file"
        exit 1
    fi
    
    # 复制依赖JAR文件（如果有）
    if [ -d "target/dependency" ]; then
        cp -r target/dependency "$OUTPUT_DIR/jar/"
        log_info "依赖JAR文件已复制"
    fi
}

# 构建Docker镜像
build_docker() {
    log_info "构建Docker镜像..."
    
    # 检查Dockerfile
    if [ ! -f "Dockerfile" ]; then
        log_error "Dockerfile不存在"
        exit 1
    fi
    
    # 设置镜像标签
    image_tag="data-gateway:${VERSION}"
    
    # 构建镜像
    log_info "构建Docker镜像: $image_tag"
    docker build -t "$image_tag" .
    
    # 保存镜像
    image_file="$OUTPUT_DIR/docker/data-gateway-${VERSION}.tar"
    log_info "保存Docker镜像: $image_file"
    docker save -o "$image_file" "$image_tag"
    
    # 压缩镜像文件
    log_info "压缩Docker镜像文件..."
    gzip "$image_file"
    
    log_info "Docker镜像构建完成: ${image_file}.gz"
}

# 复制配置文件
copy_config_files() {
    log_info "复制配置文件..."
    
    # 复制应用配置
    if [ -f "src/main/resources/application.yml" ]; then
        cp src/main/resources/application.yml "$OUTPUT_DIR/config/"
    fi
    
    if [ -f "src/main/resources/application-prod.yml" ]; then
        cp src/main/resources/application-prod.yml "$OUTPUT_DIR/config/"
    fi
    
    # 复制Docker配置
    if [ -f "docker-compose.yml" ]; then
        cp docker-compose.yml "$OUTPUT_DIR/config/"
    fi
    
    if [ -f "Dockerfile" ]; then
        cp Dockerfile "$OUTPUT_DIR/config/"
    fi
    
    # 复制启动脚本
    if [ -f "docker/entrypoint.sh" ]; then
        cp docker/entrypoint.sh "$OUTPUT_DIR/scripts/"
        chmod +x "$OUTPUT_DIR/scripts/entrypoint.sh"
    fi
    
    log_info "配置文件复制完成"
}

# 复制文档
copy_documentation() {
    log_info "复制文档..."
    
    # 复制README
    if [ -f "README.md" ]; then
        cp README.md "$OUTPUT_DIR/docs/"
    fi
    
    # 复制部署文档
    if [ -f "DEPLOYMENT.md" ]; then
        cp DEPLOYMENT.md "$OUTPUT_DIR/docs/"
    fi
    
    # 复制操作日志
    if [ -f "operatelog.md" ]; then
        cp operatelog.md "$OUTPUT_DIR/docs/"
    fi
    
    log_info "文档复制完成"
}

# 创建部署包
create_deployment_package() {
    log_info "创建部署包..."
    
    # 创建部署脚本
    cat > "$OUTPUT_DIR/deploy.sh" << 'EOF'
#!/bin/bash

# 数据网关部署脚本
# 自动生成的部署脚本

set -e

echo "开始部署数据网关..."

# 检查Docker
if ! command -v docker &> /dev/null; then
    echo "错误: Docker未安装"
    exit 1
fi

# 加载Docker镜像
if [ -f "docker/data-gateway-*.tar.gz" ]; then
    echo "加载Docker镜像..."
    docker load -i docker/data-gateway-*.tar.gz
fi

# 启动服务
if [ -f "config/docker-compose.yml" ]; then
    echo "启动服务..."
    docker-compose -f config/docker-compose.yml up -d
fi

echo "部署完成！"
echo "访问地址: http://localhost:8080/data-gateway/api/health/status"
EOF
    
    chmod +x "$OUTPUT_DIR/deploy.sh"
    
    # 创建版本信息文件
    cat > "$OUTPUT_DIR/version.txt" << EOF
数据网关版本信息
================

版本号: ${VERSION}
构建时间: $(date '+%Y-%m-%d %H:%M:%S')
构建用户: $(whoami)
构建主机: $(hostname)
Git提交: $(git rev-parse HEAD 2>/dev/null || echo "N/A")
Java版本: $(java -version 2>&1 | head -n 1)
Maven版本: $(mvn -version | head -n 1)
Docker版本: $(docker --version 2>/dev/null || echo "N/A")

文件清单:
- jar/data-gateway-${VERSION}.jar
- docker/data-gateway-${VERSION}.tar.gz
- config/application*.yml
- config/docker-compose.yml
- config/Dockerfile
- scripts/entrypoint.sh
- docs/README.md
- docs/DEPLOYMENT.md
- deploy.sh
- version.txt
EOF
    
    log_info "部署包创建完成"
}

# 创建压缩包
create_archive() {
    log_info "创建压缩包..."
    
    archive_name="data-gateway-${VERSION}-$(date +%Y%m%d_%H%M%S)"
    archive_file="${archive_name}.tar.gz"
    
    # 创建压缩包
    tar -czf "$archive_file" -C "$OUTPUT_DIR" .
    
    # 计算文件大小
    file_size=$(du -h "$archive_file" | cut -f1)
    
    log_info "压缩包创建完成: $archive_file"
    log_info "文件大小: $file_size"
    
    # 显示文件清单
    log_info "压缩包内容:"
    tar -tzf "$archive_file" | head -20
    if [ $(tar -tzf "$archive_file" | wc -l) -gt 20 ]; then
        echo "... (共 $(tar -tzf "$archive_file" | wc -l) 个文件)"
    fi
}

# 显示打包信息
show_package_info() {
    log_info "打包信息:"
    log_info "  版本: $VERSION"
    log_info "  类型: $PACKAGE_TYPE"
    log_info "  输出目录: $OUTPUT_DIR"
    log_info "  构建时间: $(date '+%Y-%m-%d %H:%M:%S')"
    log_info "  构建用户: $(whoami)"
    log_info "  构建主机: $(hostname)"
    
    if [ -d "$OUTPUT_DIR" ]; then
        log_info "  输出文件:"
        find "$OUTPUT_DIR" -type f | while read file; do
            size=$(du -h "$file" | cut -f1)
            log_info "    $file ($size)"
        done
    fi
}

# 主函数
main() {
    # 默认参数
    VERSION="1.0.0"
    PACKAGE_TYPE="all"
    OUTPUT_DIR="dist"
    SKIP_TESTS=false
    SKIP_DOCKER=false
    CLEAN_BUILD=false
    
    # 解析命令行参数
    while [[ $# -gt 0 ]]; do
        case $1 in
            -h|--help)
                show_help
                exit 0
                ;;
            -v|--version)
                VERSION="$2"
                shift 2
                ;;
            -t|--type)
                PACKAGE_TYPE="$2"
                shift 2
                ;;
            -o|--output)
                OUTPUT_DIR="$2"
                shift 2
                ;;
            --skip-tests)
                SKIP_TESTS=true
                shift
                ;;
            --skip-docker)
                SKIP_DOCKER=true
                shift
                ;;
            --clean)
                CLEAN_BUILD=true
                shift
                ;;
            *)
                log_error "未知参数: $1"
                show_help
                exit 1
                ;;
        esac
    done
    
    # 验证参数
    if [[ ! "$PACKAGE_TYPE" =~ ^(jar|docker|all)$ ]]; then
        log_error "无效的打包类型: $PACKAGE_TYPE"
        exit 1
    fi
    
    # 显示打包信息
    show_package_info
    
    # 检查依赖
    check_dependencies
    
    # 清理构建目录
    if [ "$CLEAN_BUILD" = true ]; then
        clean_build
    fi
    
    # 创建输出目录
    create_output_dir
    
    # 执行打包
    if [ "$PACKAGE_TYPE" = "jar" ] || [ "$PACKAGE_TYPE" = "all" ]; then
        package_jar
    fi
    
    if [ "$PACKAGE_TYPE" = "docker" ] || [ "$PACKAGE_TYPE" = "all" ]; then
        if [ "$SKIP_DOCKER" = false ]; then
            build_docker
        fi
    fi
    
    # 复制配置和文档
    copy_config_files
    copy_documentation
    
    # 创建部署包
    create_deployment_package
    
    # 创建压缩包
    create_archive
    
    log_info "打包完成！"
    log_info "输出目录: $OUTPUT_DIR"
    log_info "压缩包: data-gateway-${VERSION}-$(date +%Y%m%d_%H%M%S).tar.gz"
}

# 执行主函数
main "$@"
